package com.dwxt.parabolic.service;

import com.dwxt.common.base.BaseResult;
import com.dwxt.common.base.Page;
import com.dwxt.common.base.StatusCode;
import com.dwxt.common.base.YesOrNo;
import com.dwxt.common.util.IDUtils;
import com.dwxt.common.util.JsonUtils;
import com.dwxt.common.util.OkHttpUtils;
import com.dwxt.parabolic.base.QuantityType;
import com.dwxt.parabolic.dao.CameraMapper;
import com.dwxt.parabolic.entity.Camera;
import com.dwxt.parabolic.entity.CameraExample;
import com.dwxt.parabolic.entity.Device;
import com.dwxt.parabolic.utils.RequestUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class CameraService {

    @Autowired
    private CameraMapper cameraMapper;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private DeviceService deviceService;

    @Value("${device.camera.count}")
    private Integer count;

    public BaseResult getCameraList(Camera camera, Page page) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        CameraExample example = new CameraExample();
        example.setOrderByClause("create_time desc");
        CameraExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(camera.getName())) {
            criteria.andNameLike("%" + camera.getName() + "%");
        }
        if (StringUtils.isNotBlank(camera.getSerial())) {
            criteria.andSerialEqualTo(camera.getSerial());
        }
        /*if (Optional.ofNullable(camera).map(Camera::getStatus).isPresent()) {
            criteria.andStatusEqualTo(camera.getStatus());
        }*/
        Optional.ofNullable(camera).map(Camera::getStatus).ifPresent(status -> {
            criteria.andStatusEqualTo(status);
        });
        criteria.andCompanyIdEqualTo(camera.getCompanyId());
        List<Camera> cameraList = cameraMapper.selectByExample(example);
        PageInfo pageInfo = new PageInfo(cameraList);
        return BaseResult.ok(pageInfo);
    }

    @Transactional
    public BaseResult add(Camera camera) {
        camera.setId(IDUtils.genItemId());
        //Camera selectBySerial = selectBySerial(camera.getSerial());
        if (selectBySerial(camera.getSerial()) != null) {
            return BaseResult.build(StatusCode.SERIAL_EXIST);
        }
        Device device = deviceService.selectByPrimaryKey(camera.getDeviceId());
        if (device.getCameraCount() >= count) {
            return BaseResult.build(StatusCode.CAMERA_LIMIT);
        }
        camera.setStatus(YesOrNo.NO);
        camera.setDeviceName(device.getName());
        cameraMapper.insertSelective(camera);
        //更改公司人员数量,数量+1
        companyService.addByQuantityType(camera.getCompanyId(), QuantityType.ipc, 1);
        //设备相机数量加1
        device.setCameraCount(device.getCameraCount() + 1);
        deviceService.updateByPrimaryKeySelective(device);
        return BaseResult.ok();
    }

    public Camera selectBySerial(String serial) {
        CameraExample example = new CameraExample();
        example.createCriteria().andSerialEqualTo(serial);
        List<Camera> cameraList = cameraMapper.selectByExample(example);
        return cameraList.size() > 0 ? cameraList.get(0) : null;
    }

    public BaseResult update(Camera camera) {
        if (Optional.ofNullable(camera).map(Camera::getSerial).map(this::selectBySerial).filter(camera1 -> !camera1.getId().equals(camera.getId())).isPresent()) {
            return BaseResult.build(StatusCode.SERIAL_EXIST);
        }
        cameraMapper.updateByPrimaryKeySelective(camera);
        return BaseResult.ok();
    }

    @Transactional
    public BaseResult delete(String id) {
        Camera camera = cameraMapper.selectByPrimaryKey(id);
        cameraMapper.deleteByPrimaryKey(id);
        companyService.addByQuantityType(camera.getCompanyId(), QuantityType.ipc, -1);
        Device device = deviceService.selectByPrimaryKey(camera.getDeviceId());
        device.setCameraCount(device.getCameraCount() - 1);
        deviceService.updateByPrimaryKeySelective(device);
        return BaseResult.ok();
    }

    public List<Camera> selectAllStartCameraOfDevice(String deviceId) {
        CameraExample example = new CameraExample();
        example.createCriteria().andDeviceIdEqualTo(deviceId);
        return cameraMapper.selectByExample(example);
    }

    public Camera selectByPrimaryKey(String cameraId) {
        return cameraMapper.selectByPrimaryKey(cameraId);
    }

    public List<Device> selectByDeviceId(String id) {
        return null;
    }

    public void updateByPrimaryKeySelective(Camera camera) {
        cameraMapper.updateByPrimaryKeySelective(camera);
    }

    public BaseResult startOrEnd(String id) {
        Camera camera = cameraMapper.selectByPrimaryKey(id);
        Device device = deviceService.selectByPrimaryKey(camera.getDeviceId());
        //调用超脑接口，启动算法
        String url = "http://" + device.getIp() + "/algorithm";
        Map para = new HashMap();
        para.put("cameraList", Arrays.asList(camera));
        para.put("action", camera.getStatus() == YesOrNo.YES ? "end" : "start");
        String res = OkHttpUtils.jsonPost(url, JsonUtils.objectToJson(para), null);
        //System.out.println(res);
        if (res == null || res.equalsIgnoreCase("Internal Server Error") || !(JSONObject.fromObject(res).getInt("status") == 200)) {
            return BaseResult.build(StatusCode.DEVICE_FAIL);
        }
        //修改设备状态
        camera.setStatus(camera.getStatus() == YesOrNo.YES ? YesOrNo.NO : YesOrNo.YES);
        if (camera.getStatus() == YesOrNo.NO) {
            camera.setDescp("摄像头关闭");
        }
        cameraMapper.updateByPrimaryKeySelective(camera);
        return BaseResult.ok();
    }

    public void startOrEndByDeviceId(String id, int status) {
        Camera camera = new Camera();
        camera.setStatus(status);
        CameraExample example = new CameraExample();
        example.createCriteria().andDeviceIdEqualTo(id);
        cameraMapper.updateByExampleSelective(camera, example);
    }
}
